#!/usr/bin/perl

######################################################################
package Swignition::uF::hRecipe;
######################################################################

use CGI::Util;
use Swignition::GenericParser::Utils;
use Swignition::uF;
use XML::LibXML qw(:all);
use strict;


sub consume
{
	my $page        = shift;

	$page->{uF}->{hRecipe} = [ parse_all($page) ];
	
	foreach my $a (@{ $page->{uF}->{hRecipe} })
	{
		$a->rdf_subject_merge($page);
	}
	
	if (defined $page->{uF}->{hRecipe}->[0])
	{
		$page->mergeNS($page->{uF}->{hRecipe}->[0]);
	}
}


sub parse_all
{
	my $page   = shift;
	my $within = shift || $page->{DOM};
	my @rv;
	
	my @nodes = searchClass('hrecipe', $within);
	foreach my $a (@nodes)
	{
		my $A = parse($page, $a);
		push @rv, $A;
	}
	
	return @rv;
} #/sub parse_all


sub uri
{
	my $this = shift;
	my $all  = shift;
	my @rv;

	if (length $this->{_id})
	{
		push @rv, $this->{_page}->uri.'#'.$this->{_id};
	}
	if (lc($this->{_dom}->tagName) eq 'body')
	{
		push @rv, $this->{_page}->uri;
	}
	push @rv, Swignition::GenericParser::Utils::BNodeURI($this->{_dom}, 'Recipe')
		unless (@rv);
	
	return $rv[0] unless (defined $all);
	while ($all) { shift @rv; $all--; }
	return @rv;
} #/sub uri


sub rdf_subject_merge
{
	my $this    = shift;
	my $page    = shift;
	my $val;
	
	my $subject = Swignition::RDFModel::Subject->new($this->uri);
	$subject->addObject($this);
	$subject->setDom($this->{_dom});
	
	$val = Swignition::RDFModel::Value->new('http://donnafales.com/2002/07/28/recipe-schema#Recipe', 1);
	$subject->addVal('http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $val);	
	
	if (length $this->{'recipe-title'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'recipe-title'});
		$subject->addVal("http://purl.org/dc/terms/title", $val);
	}
	
	if (length $this->{'recipe-summary'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'recipe-summary'});
		$subject->addVal("http://purl.org/dc/terms/abstract", $val);
	}

	foreach my $x (@{ $this->{'author'} })
	{
		if (UNIVERSAL::can($x, 'uri'))
			{ $val = Swignition::RDFModel::Value->new($x->uri, 1); }
		else
			{ $val = Swignition::RDFModel::Value->new($x); }
		$subject->addVal("http://purl.org/dc/terms/creator", $val);
	}

	foreach my $x (@{ $this->{'published'} })
	{
		$val = Swignition::RDFModel::Value->new($x);
		$subject->addVal("http://purl.org/dc/terms/issued", $val);
	}

	foreach my $x (@{ $this->{'photo'} })
	{
		$val = Swignition::RDFModel::Value->new($x, 1);
		$subject->addVal("http://purl.org/media#depiction", $val);
	}
	
	foreach my $x (@{ $this->{'ingredients'} })
	{
		$x->rdf_subject_merge($page);
		$val = Swignition::RDFModel::Value->new($x->uri, 1);
		$subject->addVal("http://donnafales.com/2002/07/28/recipe-schema#ingredient", $val);
	}

	if (length $this->{'method'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'method'});
		$subject->addVal("http://donnafales.com/2002/07/28/recipe-schema#directions", $val);
		$val = Swignition::RDFModel::Value->new($this->{'html_method'});
		$val->setDatatype('http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral');
		$subject->addVal("http://donnafales.com/2002/07/28/recipe-schema#directions", $val);
	}
	
	if (length $this->{'yield'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'yield'});
		$subject->addVal("http://donnafales.com/2002/07/28/recipe-schema#x-yield", $val);
	}

	if (length $this->{'preparation-time'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'preparation-time'});
		$subject->addVal("http://donnafales.com/2002/07/28/recipe-schema#x-preparation-time", $val);
	}
	
	foreach my $tag (@{$this->{'category'}})
	{
		$subject->addVal('http://www.holygoat.co.uk/owl/redwood/0.1/tags/taggedWithTag',
			Swignition::RDFModel::Value->new($tag->uri, 1));
		$subject->addVal('http://www.holygoat.co.uk/owl/redwood/0.1/tags/tag',
			Swignition::RDFModel::Value->new($tag->uri_tagging, 1));
	}

	$page->mergeSubject($subject);
	
} #/sub rdf_subject_merge


sub metadata_ns
{
	my $this = shift;
	return {
		'recipe' => {
			nsurl=>'http://donnafales.com/2002/07/28/recipe-schema#',
			title=>'RDF Recipe'
		},
		'media' => {
			nsurl=>'http://purl.org/media#',
			title=>'RDF Media Vocabulary'
		}
	};
} #/sub metadata_ns


sub parse
{
	my $page  = shift;
	my $rv    = { '_dom'=>shift };
	my $pkg = __PACKAGE__;
	if (defined $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') })
		{ return $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') }; }
	else
		{ $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') } = $rv; }
	
	my $root  = $rv->{'_dom'}->cloneNode(1);
	
	my $id = $root->getAttribute('id');
	$rv->{_id} = $id if (length $id);
	$rv->{_page} = $page;
		
	data_patterns($page, $root, 2);
	
	my @ilists = searchClass('ingredients', $root);
	foreach my $ilist (@ilists)
	{
		foreach my $i ($ilist->getChildrenByTagName('*'))
		{
			$i->setAttribute('class', 'ingredient '.$i->getAttribute('class'));
		}
	}

	simple_parse(
		$rv,
		$root,
		[
			['recipe-title',     '1'],
			['recipe-summary',   '?'],
			['author',           'M*', {embedded=>'hCard'}],
			['published',        'd*'],
			['photo',            'u*'],
			['method',           'H&', {'include-self'=>1}],
			['yield',            '?'],
			['preparation-time', 'D?']
		],
		{
			'rel-tag' => 'category',
			'no-destroy' => ['hmeasure']			
		}
	);
	
	my @ingredients = searchClass('ingredient', $root);
	foreach my $i (@ingredients)
	{
		push @{$rv->{ingredients}}, Swignition::uF::hRecipe::I::parse($page, $i);
	}

	bless $rv;
	return $rv;
	
} #/sub parse


1; #/package Swignition::uF::hRecipe



package Swignition::uF::hRecipe::I;
use Swignition::GenericParser::Utils;
use Swignition::uF;
use XML::LibXML qw(:all);
use strict;


sub uri
{
	my $this = shift;
	my $all  = shift;
	my @rv;

	if (length $this->{_id})
	{
		push @rv, $this->{_page}->uri.'#'.$this->{_id};
	}
	if (lc($this->{_dom}->tagName) eq 'body')
	{
		push @rv, $this->{_page}->uri;
	}
	push @rv, Swignition::GenericParser::Utils::BNodeURI($this->{_dom}, 'RecipeIngredient')
		unless (@rv);
	
	return $rv[0] unless (defined $all);
	while ($all) { shift @rv; $all--; }
	return @rv;
} #/sub uri


sub rdf_subject_merge
{
	my $this    = shift;
	my $page    = shift;
	my $val;
	
	my $subject = Swignition::RDFModel::Subject->new($this->uri);
	$subject->addObject($this);
	$subject->setDom($this->{_dom});
	
	$val = Swignition::RDFModel::Value->new('http://donnafales.com/2002/07/28/recipe-schema#Ingredient', 1);
	$subject->addVal('http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $val);	

	if ('Swignition::uF::hMeasure' eq ref $this->{'quantity'})
	{
		$subject->addVal((length $this->{'quantity'}->dim_uri ? $this->{'quantity'}->dim_uri : 'http://buzzword.org.uk/rdf/measure#quantity'),
			Swignition::RDFModel::Value->new($this->{'quantity'}->qv_uri, 1));
	}
	elsif ($this->{'quantity'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'quantity'});
		$subject->addVal('http://buzzword.org.uk/rdf/measure#quantity', $val);
	}

	if ('Swignition::uF::species' eq ref $this->{'item'})
	{
		# This doesn't seem to work (TODO)
		$val = Swignition::RDFModel::Value->new($this->{'item'}->uri, 1);
		$subject->addVal('http://purl.org/NET/biol/ns#hasTaxonomy', $val);
	}
	elsif ($this->{'item'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'item'});
		$subject->addVal('http://www.w3.org/1999/02/22-rdf-syntax-ns#value', $val);
	}	

	if (length $this->{'note'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'note'});
		$subject->addVal("http://purl.org/dc/terms/abstract", $val);
	}	

	if (length $this->{'optional'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'optional'});
		$subject->addVal("http://purl.org/dc/terms/abstract", $val);
	}	

	if (length $this->{'label'})
	{
		$val = Swignition::RDFModel::Value->new($this->{'label'});
		$subject->addVal("http://www.w3.org/2000/01/rdf-schema#label", $val);
	}	

	$page->mergeSubject($subject);
}


sub parse
{
	my $page  = shift;
	my $rv    = { '_dom'=>shift };
	my $pkg = __PACKAGE__;
	if (defined $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') })
		{ return $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') }; }
	else
		{ $page->{uF}->{_Shortcuts}->{$pkg}->{ $rv->{_dom}->getAttribute('_xpath') } = $rv; }
	
	my $root  = $rv->{'_dom'}->cloneNode(1);
	
	my $id = $root->getAttribute('id');
	$rv->{_id} = $id if (length $id);
	$rv->{_page} = $page;
		
	data_patterns($page, $root, 2);

	simple_parse(
		$rv,
		$root,
		[
			['quantity',  'M?', {embedded=>'hMeasure'}],
			['item',      'M1', {embedded=>'species'}],
			['note',      '?'],
			['optional',  '?']
		]
	);
	
	$rv->{item} = $rv->{quantity}->{item}
		if (('Swignition::uF::hMeasure' eq ref $rv->{quantity}) && !$rv->{item});
	
	$rv->{item} = STRINGIFY($root, {'abbr-pattern'=>1})
		if (! $rv->{item});
		
	$rv->{label} = STRINGIFY($root, {'abbr-pattern'=>1});

	bless $rv;
	return $rv;	
}

1; #/package Swignition::uF::hRecipe::I
